<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="https://openlayers.org/en/v5.3.0/css/ol.css" />
    <script type="text/javascript" src="https://openlayers.org/en/v5.3.0/build/ol.js"></script>
    <script type="text/javascript"
        src="https://cdn.bootcdn.net/ajax/libs/FileSaver.js/2014-11-29/FileSaver.min.js"></script>
    <!-- https://html2canvas.hertzen.com/configuration -->
    <script src="https://cdn.bootcdn.net/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>

    <title>html2canvas 截图</title>
    <style>
        .img-container {
            border: 1px solid black;
        }

        .img-container2 {
            border: 1px solid blueviolet;
        }

        img {
            display: block;
        }
    </style>
</head>

<body>
    <div id="map"></div>
    <button id="btn" onclick="toImg()">方式1：html2canvas</button>
    <div class="img-container">
        截图html2canvas
        <pre>
      引自<a href=" https://html2canvas.hertzen.com/faq">html2canvas</a> 官网
      <!-- 无法支持适配所有的css样式 -->
      As each CSS property needs to be manually coded
      to render correctly, html2canvas will never have full CSS support. The
      library tries to support the most commonly used CSS properties to the
      extent that it can. If some CSS property is missing or incomplete and you
      feel that it should be part of the library, create test cases for it and a
      new issue for it.
    </pre>
    </div>
    <button id="btn" onclick="onlyImg()">方式2：canvas实现</button>
    <div class="img-container2">
        canvas实现 不能截图到工具(例如上面的 zoom)
        <br />
    </div>
    <button id="btn" onclick="toImg3()">方式3：postcompose实现</button>
    <div class="img-container3">
        方式3：postcompose实现
        <br />
    </div>
    <script>
        var map = new ol.Map({
            target: "map",
            layers: [
                // 可以被截图
                new ol.layer.Tile({
                    // 初始化Tile外部图层
                    source: new ol.source.XYZ({
                        // 初始化XYZ切片服务图层
                        //   url 服务的配置起决定因素 是否能够使用 htmltocanvas
                        crossOrigin: "anonymous", //跨域加这行代码，加上该代码即可
                        url: "http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}",
                    }),
                }),
                new ol.layer.Tile({
                    // 初始化Tile外部图层
                    source: new ol.source.XYZ({
                        // 初始化XYZ切片服务图层
                        url: "http://t{0-7}.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=5d27dc75ca0c3bdf34f657ffe1e9881d", // XYZ切片服务地址
                        wrapX: false,
                        crossOrigin: "anonymous",
                    }),
                }),
                new ol.layer.Tile({
                    // 初始化Tile外部图层
                    source: new ol.source.XYZ({
                        // 初始化XYZ切片服务图层
                        url: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}", // XYZ切片服务地址
                        wrapX: false,
                        crossOrigin: "anonymous",
                    }),
                }),
                new ol.layer.Tile({
                    // 初始化Tile外部图层
                    source: new ol.source.XYZ({
                        // 初始化XYZ切片服务图层
                        url: "http://t{0-7}.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=5d27dc75ca0c3bdf34f657ffe1e9881d", // XYZ切片服务地址
                        wrapX: false,
                        crossOrigin: "anonymous",
                    }),
                }),
            ],
            view: new ol.View({
                center: [91.1, 30.41],
                zoom: 4,
            }),
        });
        function toImg() {
            html2canvas(document.querySelector("#map"), {
                // scale: 2,
            }).then((canvas) => {
                const dataURL = canvas.toDataURL("images/png", 1);
                const imgContainer = document.querySelector(".img-container");
                const img = document.createElement("img");
                img.src = dataURL;
                img.style.width = document.querySelector("#map").offsetWidth + "px";
                img.style.height = document.querySelector("#map").offsetHeight + "px";
                imgContainer.appendChild(img);
            });
        }

        // 2
        function onlyImg() {
            // 只是地图
            let canvas = map.getViewport().querySelector("canvas");
            let dataURL = canvas.toDataURL("image/png");
            const imgContainer = document.querySelector(".img-container2");
            const img = document.createElement("img");
            img.src = dataURL;
            img.style.width = document.querySelector("#map").offsetWidth + "px";
            img.style.height = document.querySelector("#map").offsetHeight + "px";
            imgContainer.appendChild(img);
        }

        // 3
        function toImg3() {
            // 这玩意 动图片实现 截图 具体不清楚怎么驱动的
            map.once("postcompose", function (event) {
                var canvas = event.context.canvas;
                let dataURL = canvas.toDataURL("image/png");
                const imgContainer = document.querySelector(".img-container3");
                const img = document.createElement("img");
                img.src = dataURL;
                img.style.width = document.querySelector("#map").offsetWidth + "px";
                img.style.height = document.querySelector("#map").offsetHeight + "px";
                imgContainer.appendChild(img);
            });
        }
    </script>
    <style>
        #map {
            width: 60%;
            height: 50%;
        }
    </style>
</body>

</html>